import re
import os
from urllib.request import urlretrieve
import logging
import colorful
def check_context_attr_with_value(context, attr:str, value):
    if attr in context and context[attr] == value:
        return True
    return False

class CQ_code_dealing():
    def __init__(self, is_pro=False):
        self.is_pro = is_pro
        self.all_CQ_codes = ['face','emoji','bface','sface','image','record','at',\
            'rps','dice','shake','anonymous','location','sign','music','share']
        self.all_CQ_codes.extend(['contact','show','rich'])
    
    def resolve_CQ_code(self, msg:str):
        '''
        解析出消息的CQ码，对应的CQ码文本存入CQ_codes, 解析出的func与key_value存入CQ_codes_funcs，
        最终返回处理后的msg2,CQ_codes,CQ_codes_parsers
        初始的msg=msg2.format(*CQ_codes)
        '''
        msg = msg.replace('{','{{')
        msg = msg.replace('}','}}')
        CQ_code_pattern = r'''\[CQ:(?P<func>.+?),(?P<key_value>.*?)\]'''
        CQ_codes = []
        CQ_codes_parsers = []
        while True:
            ret = re.search(CQ_code_pattern, msg)
            if ret == None:
                break
            else:
                msg = msg[:ret.start()] + "{}" + msg[ret.end():]
                CQ_codes_parsers.append(ret.groupdict())
                CQ_codes.append(ret.group())
        return msg, CQ_codes, CQ_codes_parsers

    def CQ_code_is_show_seperately(self, func:str):
        return func in ['contact','bface','record','rps','dice','location','music','share']
    
    def resolve_CQ_key_value(self, key_value:str)->dict:
        '''
        根据CQ码的key_value部分解析成字典。
        例如：
        key_value='file=1.silk,magic=true'
        return {'file': '1.silk', 'magic': 'true'}
        '''
        key_values = key_value.split(',')
        ans = dict()
        for v in key_values:
            u = v.split('=')
            ans[u[0]] = u[1]
        return ans

    def CQ_code_to_readable(self, CQ_code_parser:dict, query_nick)->str:
        '''
        @param[CQ_code_parser]: a dict that contains key: 'func' and 'key_value'
        @param[query_nick]: a function returns nickname to given user_id
        @return 返回可读的CQ代码（暂时默认为Pro）
        '''
        func: str = CQ_code_parser['func']
        key_value: str = CQ_code_parser['key_value']
        d = self.resolve_CQ_key_value(key_value)
        if func == 'bface':
            return "[大表情↓↓↓]"
        if func == 'record':
            return "[语音↓↓↓]"
        if func == 'at':
            if d['qq'] == 'all':
                return "[@全体成员]"
            else:
                nick = query_nick(int(d['qq']))
                return "[@{nick}]".format(nick=nick)
        if func == 'rps':
            if d['type']=='1':
                return "[猜拳（石头）↓↓↓]"
            elif d['type']=='2':
                return "[猜拳（剪刀）↓↓↓]"
            elif d['type']=='3':
                return "[猜拳（布）↓↓↓]"
            else:
                return "[猜拳↓↓↓]"
        if func == 'dice':
            return '[摇骰子（{}点）↓↓↓]'.format(d['type'])
        if func == 'shake':
            return '[戳一戳]'
        if func == 'sign':
            return '[在{}签到：{}]'.format(d['location'],d['title'])
        if func == 'location':
            return '[定位（{}）:{}↓↓↓]'.format(d['content'],d['title'])
        if func == 'music':
            return '[分享音乐↓↓↓]'
        if func == 'share':
            return '[链接分享（{}）：{}↓↓↓]'.format(d['title'], d['url'])
        if func == 'contact':
            return '[推荐了联系人({})↓↓↓]'.format(d['id'])
        if func == 'show':
            logging.info("出现了，厘米秀！内容：{}".format(d))
            return '[未解析的厘米秀]'
        if func == 'rich':
            return '[未解析的分享↓↓↓]'
        return '[CQ:{func},{key_value}]'.format(func=func,key_value=key_value)


class query_group_info():
    from cqhttp import CQHttp
    cache=dict()
    def query_all(bot:CQHttp, group_id:int):
        '''
        返回对应群号的所有信息
        '''
        try:
            if group_id not in query_group_info.cache:
                query_group_info.cache[group_id] = bot._get_group_info(group_id=group_id)
            return query_group_info.cache[group_id]
        except:
            logging.debug(colorful.yellow("warning: query info of group {} failed!".format(group_id)))
            query_group_info.cache[group_id] = None
            return None
    def query_name(bot:CQHttp, group_id:int):
        '''
        返回群号为group_id的群名称
        '''
        info = query_group_info.query_all(bot, group_id)
        if info:
            return info['group_name']
        else:
            return '未知群名'

    def flash():
        query_group_info.cache.clear()
            


class group_msg_level():
    ILLEGAL=-1
    ANONYMOUS=0
    MEMBER=1
    ADMIN=2
    OWNER=3
    PURCHASER=4
    MASTER=5
    def judge(context, master_qqs=[]):
        if context['message_type'] != 'group':
            return group_msg_level.ILLEGAL
        if context['anonymous'] != None:
            return group_msg_level.ANONYMOUS

        if context['user_id'] in master_qqs:
            return group_msg_level.MASTER
        if 'role' not in context['sender']:
            logging.warning("no role information in a group msg")
            return group_msg_level.MEMBER
        if context['sender']['role'] == 'owner':
            return group_msg_level.OWNER
        if context['sender']['role'] == 'admin':
            return group_msg_level.ADMIN
        if context['sender']['role'] == 'member':
            return group_msg_level.MEMBER


def img_url_to_CQCode(url):
    filename, _ = urlretrieve(url)
    abspath=os.path.abspath(filename)
    code="[CQ:image,file=file:///{}]".format(abspath)
    return code

def download_img_from_url(url):
    '''
    if url match mattern, resolve its md5,
    else calc md5 to url.
    use {md5}.jpg as filename
    return filepath to image and http
    '''
    pattern=r'https?://(.*?)/(.*?)/(.*?)/(.*?)-(.*?)-(?P<md5>.*?)/(.*?)'
    ret = re.match(pattern,url)
    if ret:
        res = ret.groupdict()
        filename='{}.jpg'.format(res['md5'])
    else:
        import hashlib
        m = hashlib.md5()
        m.update(url.encode())
        filename='{}.jpg'.format(m.hexdigest())
    return urlretrieve(url,filename)